命名空间

所谓的命名空间说白了就是避免名字冲突.

假如全世界没有国家, 班级, 学校等概念. 有两个员工叫张三,老板喊了一句:张三过来扫厕所. 两个张三都会去扫厕所. 这就造成了冲突. 但如果一个张三是清华大学的, 另一个张三是北京大学的. 这时候老板喊: 北京大学那个张三过来扫厕所. 那么就不会造成混淆了.

编程语言的命名空间就是用来区分不同对象(万物皆对象,包括基础数据类型),这样就不会造成混淆.

闭包

很多语言都有包的概念进行命名空间的管理, 比如java,php等. 但js是没有包概念的. js实现命名空间管理是使用闭包的概念.

正常情况下,js只有全局变量和局部变量.全局变量全部绑定到终极对象window上面, 而局部变量在函数执行完成后会被销毁. 但如果我们让一个全局变量指向一个对象,window.$={}. 那么该对象就是命名空间, 里面的变量虽然是局部变量, 但是因为有全局变量引用,所以并不会被销毁.

下面例子 a,b,c变量都是直接绑定到window上面. 对于c变量,你可以调用c.b()而不会和b()冲突. 那是因为c变量指向的是一个封闭的对象. 这个对象就是一个命名空间.

window={}
var window.a='aaa'
var window.b=function(){return 'bbb'}
var window.c={a:'ccc',b:function(){return 'ddd'}}//重点注意

闭包只是命名空间的实现而已,没什么稀奇的.

下面例子 就是一个闭包, 先定义一个匿名函数, 再立马执行. 传入了window对象作为参数. 当执行完毕后, window对象就有了$属性, 并绑定了一个对象.

window = {};
(function(win){
    win.$={
        a:'ccc',
        b:function(){return 'ddd'}
    }
})(window)
console.log(window)
//{ '$': { a: 'ccc', b: [Function: b] } }

如果你导入一个对象并赋值给window对象的属性,不用闭包也是一样!

global

js有window全局对象,nodejs有global全局对象.

我们知道nodejs引入外部模块格式const hello=require('./hello'), 其实正真的格式是:

global = {}
const global.hello=require('./hello')

也就是说你导入的文件被global下的一个属性引用, 和js下的window引用属性无任何区别.

exports vs module.exports

重头戏来了,很多人搞不清楚exports和module.exports的区别,它们都可以用来导出模块.下面我们来分析过程.

  1. const path=require('path')这句话其实是调用global的require方法,根据路径找到文件,并把文件实例化一个对象绑定到global.path的属性下面.
//假如下面就是文件的对象,我们在对象里定义了三个方法a,b,c
{
    //global实例化该文件时把内部参数封装到module中,这个我们不用管.只需要知道有个exports={}属性
    let module={
        exports={}
    }
    let exports=module.exports
    //我们定义的函数
    function a(){return 'aaa'}
    function b(){return 'bbb'}
    function c(){return 'ccc'}
    //我们需要导出什么直接赋值
    module.exports.a=a
    module.exports.b=b
    exports.c=c
    //最终返回的就是它
    return module.exports
    //最后返回{a函数,b函数,c函数}
}

上面let exports=module.exports就是重点, 这也就是为什么我们通过添加属性的方式导出, module.exports和exports是等价的. 但是下面这种方式只有module.exports有效,exports是无效的.

{
    let module={
        exports={}
    }
    let exports=module.exports
    function a(){return 'aaa'}
    function b(){return 'bbb'}
    function c(){return 'ccc'}
    exports=a
    return module.exports
    //最后返回空对象{}
}

原因解析: 因为exports变量一开始指向module.exports, 但exports=c直接修改了exports变量的指向, 它不再指向于module.exports. 我们根本没有对module.exports做任何操作,所以最后返回的还是一个空对象, 并不是a函数.

结束语

看完这篇文章,相信大家对于exports和module.exports有了深入理解,可喜可贺可喜可贺

THE END
推荐文章
  • taro报错 Can't resolve './style/index.scss'

  • freshrss设置api登录,用来连接其他客户端

  • OneDrive损坏后重装

  • linux上编译安装php

  • 保存vscode配置的同步插件设置

  • 如何有效的减肥

  • gtd思想的个性化

  • 解决wordpress中自定义类型或page类型的分页查询404问题

评论 共0条
开启精彩搜索

热门搜索

暂无

历史搜索

用户名/邮箱/手机号
密码
用户名
密码
重复密码
邮箱/手机号
验证码
发送验证码
59秒后可重发
注册
找回密码
邮箱/手机号
验证码
发送验证码
59秒后可重发
新密码
重复密码
请选择支付方式
余额支付

购买将消耗【10

微信支付
微信扫码支付 0 元
[ 04分50秒 ]
请使用微信扫一扫
扫描二维码支付
支付宝支付
支付宝扫码支付 0 元
[ 04分50秒 ]
请使用支付宝扫一扫
扫描二维码支付
已完成支付
未完成支付

请输入验证码

点击验证码可以刷新

你确认吗?

确认

2024年10月1日

0字

0字

2024年10月

0字

新增

0字

新增

0字

0字

新增

0字

0字

新增

0字

0字

新增

0字

0字

新增

0字

0字

新增

0字

0字

新增

0字

0字

0字

新增

0字

0字

0字

0字

新增

0字

0字